/*
 * @Description:
 * @Author: maxyang
 * @Date: 2022-08-09 12:15:17
 * @LastEditTime: 2022-08-10 17:00:39
 * @LastEditors: liutq
 * @Reference:
 */
package service

import (
	"errors"
	"fmt"
	"log"
	"strconv"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/maxyang107/jinglan/aliyun"
	"github.com/maxyang107/jinglan/common"
	"github.com/maxyang107/jinglan/model"
	"github.com/maxyang107/jinglan/model/goods"
	"github.com/maxyang107/jinglan/model/user"
	"github.com/smartwalle/alipay/v3"
	"github.com/smartwalle/xid"
)

var (
	PayService = &PaySer{}
)

type PaySer struct{}

func (pay PaySer) DealPay(payParam common.Detail) (string, error) {
	//获取商品详情
	gt := goods.GetGoodsDetail(int(payParam.Id))

	if gt.ID == 0 {
		return "", errors.New("商品不存在或不支持购买")
	}

	//检查用户是否符合购买条件
	if gt.GoodsOptionId != 0 && gt.GoodsKind == 1 {
		mc := user.GetUserCollectByGoodsId(payParam.UserId, gt.GoodsOptionId)
		if mc.ID == 0 {
			return "", errors.New("抱歉，您不符合购买条件")
		}
	}

	if gt.GoodsCate == 3 {
		dr := goods.GetDrawRecordByUid(payParam.UserId)
		if dr.ID == 0 {
			return "", errors.New("抱歉，您不符合购买条件")
		}
	}

	//检查用户是否有未支付订单
	if user.GetMyCollectByGoodsIdAndUserId(gt.ID, payParam.UserId) {
		return "", errors.New("存在未支付的订单，请5分钟以后重试")
	}

	//扣库存
	err := goods.ModifyStock(gt.ID, 1, false)
	if err != nil {
		return "", err
	}

	var tradeNo = fmt.Sprintf("%d", xid.Next())
	user.Buildcollect(&gt, payParam.UserId, 1, tradeNo, gt.GoodsKind, 0)
	seedtime, _ := time.ParseDuration("1m")
	now := time.Now()
	expire_ := now.Add(seedtime)
	//增加订单超时处理
	model.AddJob(tradeNo, expire_)

	var p = alipay.TradePagePay{}
	p.NotifyURL = "https://api.jinglan.art/api/aliNotify"
	p.ReturnURL = fmt.Sprintf("https://h5.jinglan.art/#/collectionDetail?id=%d&list=true", gt.ID)
	p.Subject = gt.GoodsName
	p.OutTradeNo = tradeNo + "_" + strconv.Itoa(int(payParam.UserId))
	p.TotalAmount = strconv.FormatFloat(float64(gt.GoodsPrice), 'f', 2, 64)
	p.ProductCode = "QUICK_WAP_PAY"

	url, _ := aliyun.AliClient.TradePagePay(p)
	return url.String(), nil
}

func (pay PaySer) DealAliNotify(c *gin.Context) error {
	ok, err := aliyun.AliClient.VerifySign(c.Request.Form)
	if err != nil {
		log.Println("异步通知验证签名发生错误", err)
		return err
	}

	if ok == false {
		log.Println("异步通知验证签名未通过")
		return errors.New("异步通知验证签名未通过")
	}

	log.Println("异步通知验证签名通过")

	var outTradeNo = c.Request.Form.Get("out_trade_no")
	var p = alipay.TradeQuery{}
	p.OutTradeNo = outTradeNo
	rsp, err := aliyun.AliClient.TradeQuery(p)
	if err != nil {
		log.Printf("异步通知验证订单 %s 信息发生错误: %s \n", outTradeNo, err.Error())
		return err
	}
	if rsp.IsSuccess() == false {
		log.Printf("异步通知验证订单 %s 信息发生错误: %s-%s \n", outTradeNo, rsp.Content.Msg, rsp.Content.SubMsg)

		return errors.New(fmt.Sprintf("异步通知验证订单 %s 信息发生错误: %s-%s \n", outTradeNo, rsp.Content.Msg, rsp.Content.SubMsg))
	}
	s := strings.Split(outTradeNo, "_")

	if len(s) != 2 {
		return errors.New("拆分订单号失败")
	}
	uid, _ := strconv.Atoi(s[1])
	err2 := user.ModifyOrder(uid, s[0], p.TradeNo)
	if err2 != nil {
		log.Printf("更新订单状态失败")
	}
	return nil
}
